"""
认证管理器模块
"""

import json
import hashlib
from pathlib import Path
from typing import Optional, Dict, Any
from datetime import datetime, timedelta


class AuthManager:
    """认证管理器"""
    
    def __init__(self):
        self.users_file = Path("data/users.json")
        self.sessions_file = Path("data/sessions.json")
        self.current_session_file = Path("data/current_session.json")
        self.remembered_users_file = Path("data/remembered_users.json")
        self.current_user = None
        self.current_session = None

        # 确保数据目录存在
        self.users_file.parent.mkdir(exist_ok=True)

        # 初始化数据文件
        self.init_data_files()

        # 尝试恢复会话
        self.restore_session()
    
    def init_data_files(self):
        """初始化数据文件"""
        # 初始化用户文件
        if not self.users_file.exists():
            default_users = {
                "admin": {
                    "password": self.hash_password("admin123"),
                    "role": "admin",
                    "name": "管理员",
                    "email": "admin@mixvideo.com",
                    "created_at": datetime.now().isoformat(),
                    "last_login": None,
                    "is_active": True,
                    "permissions": ["all"]
                }
            }
            self.save_json(self.users_file, default_users)
        
        # 初始化会话文件
        if not self.sessions_file.exists():
            self.save_json(self.sessions_file, {})

        # 初始化当前会话文件
        if not self.current_session_file.exists():
            self.save_json(self.current_session_file, {})

        # 初始化记住的用户文件
        if not self.remembered_users_file.exists():
            self.save_json(self.remembered_users_file, {})
    
    def hash_password(self, password: str) -> str:
        """密码哈希"""
        return hashlib.sha256(password.encode()).hexdigest()
    
    def load_json(self, file_path: Path) -> dict:
        """加载JSON文件"""
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                return json.load(f)
        except:
            return {}
    
    def save_json(self, file_path: Path, data: dict):
        """保存JSON文件"""
        try:
            with open(file_path, 'w', encoding='utf-8') as f:
                json.dump(data, f, ensure_ascii=False, indent=2)
        except Exception as e:
            print(f"保存文件失败 {file_path}: {e}")
    
    def authenticate(self, username: str, password: str, remember_me: bool = False) -> bool:
        """用户认证"""
        users_data = self.load_json(self.users_file)

        if username not in users_data:
            return False

        user_data = users_data[username]

        # 检查用户是否激活
        if not user_data.get("is_active", True):
            return False

        # 验证密码
        if user_data["password"] != self.hash_password(password):
            return False

        # 更新最后登录时间
        user_data["last_login"] = datetime.now().isoformat()
        users_data[username] = user_data
        self.save_json(self.users_file, users_data)

        # 设置当前用户
        self.current_user = {
            "username": username,
            **user_data
        }

        # 创建会话
        self.create_session(username, remember_me)

        # 如果选择记住密码，保存用户信息
        if remember_me:
            self.save_remembered_user(username, password)

        return True
    
    def create_session(self, username: str, remember_me: bool = False):
        """创建用户会话"""
        session_id = hashlib.md5(f"{username}_{datetime.now().isoformat()}".encode()).hexdigest()

        # 如果选择记住登录，会话有效期为30天，否则为24小时
        expires_hours = 24 * 30 if remember_me else 24

        session_data = {
            "username": username,
            "created_at": datetime.now().isoformat(),
            "expires_at": (datetime.now() + timedelta(hours=expires_hours)).isoformat(),
            "is_active": True,
            "remember_me": remember_me
        }

        sessions = self.load_json(self.sessions_file)
        sessions[session_id] = session_data
        self.save_json(self.sessions_file, sessions)

        self.current_session = session_id

        # 保存当前会话ID到文件
        current_session_data = {
            "session_id": session_id,
            "username": username,
            "saved_at": datetime.now().isoformat()
        }
        self.save_json(self.current_session_file, current_session_data)
    
    def logout(self):
        """用户登出"""
        if self.current_session:
            # 标记会话为非活跃
            sessions = self.load_json(self.sessions_file)
            if self.current_session in sessions:
                sessions[self.current_session]["is_active"] = False
                self.save_json(self.sessions_file, sessions)

        # 清除当前会话文件
        self.save_json(self.current_session_file, {})

        self.current_user = None
        self.current_session = None
    
    def is_logged_in(self) -> bool:
        """检查是否已登录"""
        return self.current_user is not None
    
    def get_current_user(self) -> Optional[Dict[str, Any]]:
        """获取当前用户信息"""
        return self.current_user
    
    def has_permission(self, permission: str) -> bool:
        """检查用户权限"""
        if not self.current_user:
            return False
        
        permissions = self.current_user.get("permissions", [])
        return "all" in permissions or permission in permissions
    
    def is_admin(self) -> bool:
        """检查是否为管理员"""
        if not self.current_user:
            return False
        return self.current_user.get("role") == "admin"
    
    def create_user(self, username: str, password: str, name: str, 
                   role: str = "user", email: str = "", permissions: list = None) -> bool:
        """创建新用户"""
        if not self.is_admin():
            return False
        
        users_data = self.load_json(self.users_file)
        
        if username in users_data:
            return False  # 用户已存在
        
        if permissions is None:
            permissions = ["read", "write"] if role == "user" else ["all"]
        
        user_data = {
            "password": self.hash_password(password),
            "role": role,
            "name": name,
            "email": email,
            "created_at": datetime.now().isoformat(),
            "last_login": None,
            "is_active": True,
            "permissions": permissions
        }
        
        users_data[username] = user_data
        self.save_json(self.users_file, users_data)
        
        return True
    
    def change_password(self, username: str, old_password: str, new_password: str) -> bool:
        """修改密码"""
        if not self.current_user:
            return False
        
        # 只能修改自己的密码，除非是管理员
        if username != self.current_user["username"] and not self.is_admin():
            return False
        
        users_data = self.load_json(self.users_file)
        
        if username not in users_data:
            return False
        
        # 如果不是管理员，需要验证旧密码
        if not self.is_admin():
            if users_data[username]["password"] != self.hash_password(old_password):
                return False
        
        # 更新密码
        users_data[username]["password"] = self.hash_password(new_password)
        self.save_json(self.users_file, users_data)
        
        return True
    
    def get_user_list(self) -> list:
        """获取用户列表（仅管理员）"""
        if not self.is_admin():
            return []
        
        users_data = self.load_json(self.users_file)
        user_list = []
        
        for username, user_data in users_data.items():
            user_info = {
                "username": username,
                "name": user_data.get("name", ""),
                "role": user_data.get("role", "user"),
                "email": user_data.get("email", ""),
                "created_at": user_data.get("created_at", ""),
                "last_login": user_data.get("last_login", ""),
                "is_active": user_data.get("is_active", True)
            }
            user_list.append(user_info)
        
        return user_list
    
    def clean_expired_sessions(self):
        """清理过期会话"""
        sessions = self.load_json(self.sessions_file)
        current_time = datetime.now()
        
        active_sessions = {}
        for session_id, session_data in sessions.items():
            try:
                expires_at = datetime.fromisoformat(session_data["expires_at"])
                if expires_at > current_time and session_data.get("is_active", True):
                    active_sessions[session_id] = session_data
            except:
                continue  # 跳过无效的会话数据
        
        self.save_json(self.sessions_file, active_sessions)

    def restore_session(self):
        """恢复会话"""
        try:
            # 清理过期会话
            self.clean_expired_sessions()

            # 读取当前会话文件
            current_session_data = self.load_json(self.current_session_file)
            if not current_session_data:
                return False

            session_id = current_session_data.get("session_id")
            username = current_session_data.get("username")

            if not session_id or not username:
                return False

            # 检查会话是否仍然有效
            sessions = self.load_json(self.sessions_file)
            if session_id not in sessions:
                return False

            session_data = sessions[session_id]
            if not session_data.get("is_active", True):
                return False

            # 检查会话是否过期
            try:
                expires_at = datetime.fromisoformat(session_data["expires_at"])
                if expires_at <= datetime.now():
                    return False
            except:
                return False

            # 恢复用户信息
            users_data = self.load_json(self.users_file)
            if username not in users_data:
                return False

            user_data = users_data[username]
            if not user_data.get("is_active", True):
                return False

            # 设置当前用户和会话
            self.current_user = {
                "username": username,
                **user_data
            }
            self.current_session = session_id

            return True

        except Exception as e:
            print(f"恢复会话失败: {e}")
            return False

    def save_remembered_user(self, username: str, password: str):
        """保存记住的用户信息"""
        remembered_users = self.load_json(self.remembered_users_file)
        remembered_users[username] = {
            "password": self.hash_password(password),
            "saved_at": datetime.now().isoformat()
        }
        self.save_json(self.remembered_users_file, remembered_users)

    def get_remembered_users(self) -> list:
        """获取记住的用户列表"""
        remembered_users = self.load_json(self.remembered_users_file)
        return list(remembered_users.keys())

    def remove_remembered_user(self, username: str):
        """移除记住的用户"""
        remembered_users = self.load_json(self.remembered_users_file)
        if username in remembered_users:
            del remembered_users[username]
            self.save_json(self.remembered_users_file, remembered_users)


# 全局认证管理器实例
auth_manager = AuthManager()
